/**
 * 
 */
package com.vision.sales.cm.db.data;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import net.sf.gilead.pojo.gwt.LightEntity;

import com.vision.sales.cm.data.PaymentTerm;


/**
 * @author Mark
 *
 */
@Entity
@Table(name = Customer.TABLE)
public class Customer extends LightEntity implements Serializable {
	
	public static interface FieldSpecs {
		int CODE_MAX = 20;
		int NAME_MAX = 100;
		int ADDRESS_MAX = 500;
		int DELIVERY_SITE_MAX = 500;
		int EMAIL_MAX = 100;
		int PHONE_MAX = 60;
		int FAX_MAX = 60;
		int CONTACT_MAX = 100;
		int CONTACT_PHONE_MAX = 60;
		int TIN_MAX = 20;
	}

	private static final long serialVersionUID = -7257781113658397700L;
	
	public static final String TABLE = "customer";
	
	// Column names
	public static final String COL_ID = "id";
	public static final String COL_CODE = "code";
	public static final String COL_NAME = "name";
	public static final String COL_ADDRESS = "address";
	public static final String COL_DELIVERY_SITE = "delivery_site";
	public static final String COL_EMAIL = "email";
	public static final String COL_PHONE = "phone";
	public static final String COL_FAX = "fax";
	public static final String COL_CONTACT_NAME = "contact_name";
	public static final String COL_CONTACT_PHONE = "contact_phone";
	public static final String COL_WITHHOLDING_TAX = "withholding_tax";
	public static final String COL_TIN = "tin";
	public static final String COL_TAX_RATE = "tax_rate";
	public static final String COL_TAX_RATE_DIRECT = "tax_rate_direct";
	public static final String COL_PAYMENT_TERMS = "payment_terms";
	public static final String COL_SALESMAN_ID = "salesman_id";
	public static final String COL_ALLOW_OVERRUNS = "allow_overruns";
	public static final String COL_OVERRUNS_RATE = "overruns_rate";
	
	public static final String COL_ADVANCE = "advance";
	public static final String COL_APPLIED_BALANCE = "applied_balance";
	public static final String COL_BALANCE = "balance";
	public static final String COL_LATEST_INVOICE_ID = "latest_invoice_id";
	
	// Fields
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "scustomer")
	@SequenceGenerator(name = "scustomer", sequenceName = "customer_seq")
	@Column(name = COL_ID)
	private Long id;
	
	@Column(name = COL_CODE, nullable = false, unique = true, updatable = false, length = FieldSpecs.CODE_MAX)
	private String code;
	
	@Column(name = COL_NAME, nullable = false, length = FieldSpecs.NAME_MAX)
	private String name;
	
	@Column(name = COL_ADDRESS, length = FieldSpecs.ADDRESS_MAX)
	private String address;

	@Column(name = COL_DELIVERY_SITE, length = FieldSpecs.DELIVERY_SITE_MAX)
	private String deliverySite;

	@Column(name = COL_EMAIL, length = FieldSpecs.EMAIL_MAX)
	private String email;

	@Column(name = COL_PHONE, length = FieldSpecs.PHONE_MAX)
	private String phone;

	@Column(name = COL_FAX, length = FieldSpecs.FAX_MAX)
	private String fax;
	
	@Column(name = COL_CONTACT_NAME, length = FieldSpecs.CONTACT_MAX)
	private String contactName;
	
	@Column(name = COL_CONTACT_PHONE, length = FieldSpecs.CONTACT_PHONE_MAX)
	private String contactPhone;
	
	/**
	 * Flag to indicate if customer has withholding tax
	 */
	@Column(name = COL_WITHHOLDING_TAX, nullable = false)
	private boolean withholdingTax;
	
	@Column(name = COL_TIN, length = FieldSpecs.TIN_MAX)
	private String tin;
	
	@Column(name = COL_TAX_RATE, nullable = false)
	private double taxRate;
	
	@Column(name = COL_TAX_RATE_DIRECT, nullable = false)
	private boolean taxRateDirect;
	
	@Column(name = COL_PAYMENT_TERMS, nullable = true)
	@Enumerated(EnumType.STRING)
	private PaymentTerm paymentTerm;
	
	@ManyToOne
	@JoinColumn(name = COL_SALESMAN_ID, nullable = false)
	private Salesman salesman;
	
	@Column(name = COL_ALLOW_OVERRUNS, nullable = false)
	private boolean allowOverruns;
	
	@Column(name = COL_OVERRUNS_RATE, nullable = false)
	private double overrunsRate;
	
	@Column(name = COL_BALANCE, nullable = false)
	private double balance;
	
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

	public Customer() { } // Serializable support
	
	@Override
	public boolean equals(Object object) {
		if (object instanceof Customer) {
			Customer customer = (Customer) object;
			return getId() != null && getId().equals(customer.getId());
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return getId() == null ? super.hashCode() : getId().hashCode();
	}
	
	@Override
	public String toString() {
		return id + ": " + name + " (" + code + ")";
	}
	
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getDeliverySite() {
		return deliverySite;
	}

	public void setDeliverySite(String deliverySite) {
		this.deliverySite = deliverySite;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}

	public String getContactName() {
		return contactName;
	}

	public void setContactName(String contactName) {
		this.contactName = contactName;
	}

	public String getContactPhone() {
		return contactPhone;
	}

	public void setContactPhone(String contactPhone) {
		this.contactPhone = contactPhone;
	}

	public boolean isWithholdingTax() {
		return withholdingTax;
	}

	public void setWithholdingTax(boolean hasTax) {
		this.withholdingTax = hasTax;
	}

	public String getTin() {
		return tin;
	}

	public void setTin(String tin) {
		this.tin = tin;
	}

	public double getTaxRate() {
		return taxRate;
	}

	public void setTaxRate(double taxRate) {
		this.taxRate = taxRate;
	}

	public boolean isTaxRateDirect() {
		return taxRateDirect;
	}

	public void setTaxRateDirect(boolean taxRateDirect) {
		this.taxRateDirect = taxRateDirect;
	}

	public PaymentTerm getPaymentTerm() {
		return paymentTerm;
	}

	public void setPaymentTerm(PaymentTerm paymentTerm) {
		this.paymentTerm = paymentTerm;
	}

	public Salesman getSalesman() {
		return salesman;
	}

	public void setSalesman(Salesman salesman) {
		this.salesman = salesman;
	}

	public boolean isAllowOverruns() {
		return allowOverruns;
	}

	public void setAllowOverruns(boolean allowOverruns) {
		this.allowOverruns = allowOverruns;
	}

	public double getOverrunsRate() {
		return overrunsRate;
	}

	public void setOverrunsRate(double overrunsRate) {
		this.overrunsRate = overrunsRate;
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}

}
